import java.io.ByteArrayOutputStream;
import java.math.BigInteger;

/**
 * @Author : lizhifeng
 * @create 2022/8/8 11:05
 * @DESC 2022/8/8 11:05
 */


public class Address {

    private static final char FIRST = '1';

    public static String convertPubKeyToAddress(byte[] pubKey) {

        try {
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            outputStream.write(0);
            byte[] ripemd160 = RIPEMD160.hash160(pubKey);
            outputStream.write(ripemd160);

            byte[] hash256 = Hash256.hash(outputStream.toByteArray());
            outputStream.write(hash256, 0, 4);
            outputStream.flush();

            byte[] data = outputStream.toByteArray();

            return "1" + Base58.encode(new BigInteger(data));
        } catch (Exception e) {
            return "";
        }
    }


    public static boolean checkAddress(String address) throws Exception {

        char first = address.charAt(0);
        if (first != FIRST) {
            return false;
        }

        address = address.substring(1);
        byte[] check = Base58.decode1(address).toByteArray();
        byte[] checkAgain = new byte[25];

        if (check.length < 25) {
            int diff = 25 - check.length;
            System.arraycopy(check, 0, checkAgain, diff, check.length);
        } else {
            checkAgain = check;
        }


        byte[] data = new byte[21];
        System.arraycopy(checkAgain, 0, data, 0, 21);

        byte[] sum = Hash256.hash(data);

        for (int i = 0; i < 4; i++) {
            if (sum[i] != checkAgain[21 + i]) {
                return false;
            }
        }

        return true;
    }


    public static void main(String[] args) throws Exception {

        String pubKey = "5F1DF16B2B704C8A578D0BBAF74D385CDE12C11EE50455F3C438EF4C3FBCF649B6DE611FEAE06279A60939E028A8D65C10B73071A6F16719274855FEB0FD8A6704";
        BigInteger bigInteger = new BigInteger(pubKey, 16);
        String address = convertPubKeyToAddress(bigInteger.toByteArray());
        System.out.println(address);

        boolean check = checkAddress(address);
        System.out.println(check);

    }

}
